package com.dapeis.web.wx.controller.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.crypto.dsig.keyinfo.RetrievalMethod;

import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import net.sf.json.util.NewBeanInstanceStrategy;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.ag.core.exception.InvalidParamException;
import com.ag.core.exception.SysTipsException;
import com.ag.core.utils.AgAssert;
import com.ag.module.common.api.service.SMSService;
import com.ag.utils.DictionarySettingUtils;
import com.ag.utils.json.AGsonBuilder;
import com.aliyun.oss.model.Owner;
import com.dapeis.core.utils.RequirementConfig;
import com.dapeis.core.utils.StringUtil;
import com.dapeis.core.utils.StylistConstants;
import com.dapeis.core.utils.UserInfoConfig;
import com.dapeis.domain.StylistCity;
import com.dapeis.domain.User;
import com.dapeis.domain.UserInformation;
import com.dapeis.domain.ext.UserExt;
import com.dapeis.service.COSFileService;
import com.dapeis.service.CosFileObjectService;
import com.dapeis.service.StylistCityService;
import com.dapeis.service.UserInformationService;
import com.dapeis.service.UserService;
import com.dapeis.web.wx.controller.IUserController;
import com.dapeis.web.wx.controller.RestController;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

/**
 * @author yuanyong
 * @date 2017年5月11日 上午10:38:42 Email: hzyuanyong@126.com
 *
 */
@Controller
@RequestMapping("/wx/user")
public class UserController extends RestController implements IUserController {
    final Logger logger = LoggerFactory.getLogger(getClass());
    @Resource
    WxMpService wxMpService;
    @Resource
    UserService userService;
    @Resource
    SMSService smsService;
    @Resource
    UserInformationService userInformationService;
    @Resource
    COSFileService cosFileService;
    @Resource
    StylistCityService stylistCityService;

    public @ResponseBody JsonElement getUserInfo(@RequestParam String code,
	    HttpServletRequest request) {
	print(request);
	WxMpOAuth2AccessToken wxMpOAuth2AccessToken;
	String msg = "";
	try {
	    logger.info("userInfo code: " + code + ",length:" + code.length());
	    System.out.println("userInfo code: " + code + ",length:"
		    + code.length());
	    wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
	    logger.info("userInfo wxMpOAuth2AccessToken: "
		    + wxMpOAuth2AccessToken.toString());
	    String wxUrl = "https://api.weixin.qq.com/cgi-bin/user/info";
	    String responseContent = this.wxMpService.get(wxUrl, "openid="
		    + wxMpOAuth2AccessToken.getOpenId() + "&lang=" + "zh_CN");
	    WxMpUser wxMpUser = WxMpUser.fromJson(responseContent);
	    logger.info("wxMpUser" + wxMpUser.toString());
	    User user = userService.getUserByWeixinOpenId(wxMpUser.getOpenId());
	    if (null == user) {
		userService.registFromWeixin(wxMpUser.getOpenId(),
			wxMpUser.getNickname(), wxMpUser.getHeadImgUrl(),
			AGsonBuilder.create().toJson(wxMpUser));
	    }
	    JsonObject json = success();
	    json.add("user", AGsonBuilder.create().toJsonTree(user));
	    return json;
	} catch (WxErrorException e) {
	    msg = e.getMessage();
	    e.printStackTrace();
	}
	throw new InvalidParamException(msg);
    }

    @Override
    public JsonElement JsapiSignature(@RequestParam String url,
	    HttpServletRequest request) {
	try {
	    // 获取 js签名参数

	    if (StringUtils.isNotBlank(url)) {
		WxJsapiSignature jsapiSignature = wxMpService
			.createJsapiSignature(url);
		logger.info("jsapi:" + jsapiSignature.toString());
		JsonObject json = success();
		json.add("jsapiSignature",
			AGsonBuilder.create().toJsonTree(jsapiSignature));
		return json;
	    }
	} catch (WxErrorException e) {
	    e.printStackTrace();
	}
	throw new InvalidParamException("获取签名失败");
    }

    @Override
    public JsonElement binding(@RequestParam String contact,
	    @RequestParam String verifyCode, HttpServletRequest request) {
	if (StringUtils.isNotBlank(contact)
		&& StringUtils.isNotBlank(verifyCode)) {
	    boolean checkResult = smsService.checkVerifyCode(
		    StylistConstants.ChannelType.USER.WECHAT_BING, contact,
		    verifyCode);
	    if (checkResult) {
		smsService.setVerifyCodeVaild(
			StylistConstants.ChannelType.USER.WECHAT_BING, contact);
		User tempUser = userService.getUserByContact(contact);
		/*
		 * 调试暂时关闭 if(tempUser != null){ //存在用户 throw new
		 * UserExistContactException(); }
		 */
		User user = getThreadLocalUser();
		user.setContact(contact);
		userService.updateByPrimaryKeySelective(user);
		JsonObject json = success();
		return json;
	    } else {
		throw new InvalidParamException("请检查手机号和验证吗");
	    }
	}
	throw new InvalidParamException("手机号或验证为空");
    }

    @Override
    public @ResponseBody JsonElement getUserInfo(HttpServletRequest request) {
	UserExt userExt = userService.getUserExtMapper().selectByPrimaryKey(
		getThreadLocalUserId());
	JsonObject json = success();
	json.add("info",
		AGsonBuilder.create().toJsonTree(userExt.getUserInformation()));
	json.addProperty("nickName", userExt.getNickName());
	json.addProperty("headImg", userExt.getHeadImg());
	json.addProperty("contact", userExt.getContact());
	return json;
    }

    @Override
    public @ResponseBody JsonElement saveUserInfo(@RequestParam Integer sex,
	    @RequestParam String faceshpe, @RequestParam String colorofskin,
	    @RequestParam String bodySize,
	    @RequestParam(required = false) String[] problem,
	    @RequestParam(required = false) String[] style,
	    @RequestParam String heigh, @RequestParam String weight,
	    @RequestParam String chest, @RequestParam String waist,
	    @RequestParam String hip,
	    @RequestParam(required = false) String professional,
	    @RequestParam(required = false) String countyCode,
	    @RequestParam(required = false) String birthday,
	    @RequestParam(required = false) MultipartFile[] lifeImg,
	    @RequestParam(required = false) String[] lifeImgIds,
	    HttpServletRequest request) {

	// 检查参数
	checkParameter(sex, faceshpe, colorofskin, bodySize, problem, style,
		heigh, weight, chest, waist, hip, professional, countyCode,
		birthday);
	// 上传图片
	String _lifeImg = doUploadImg(lifeImg, request, lifeImgIds);
	// 初始化
	UserInformation information = initData(sex, faceshpe, colorofskin,
		bodySize, problem, style, heigh, weight, chest, waist, hip,
		professional, countyCode, birthday);
	Integer userId = getThreadLocalUserId();
	information.setUserId(userId);
	if (StringUtil.isNotBlank(_lifeImg)) {
	    information.setLifeImg(_lifeImg);
	}
	UserInformation dbObjectInformation = userInformationService
		.getUserInformationByUserId(userId);
	if (null == dbObjectInformation)
	    userInformationService.insertSelective(information);
	else {
	    information.setId(dbObjectInformation.getId());
	    userInformationService.updateByPrimaryKeySelective(information);
	}
	User user = getThreadLocalUser();
	if (user.getInfoId() == null) {
	    user.setInfoId(information.getId());
	    userService.updateByPrimaryKeySelective(user);
	}
	JsonObject json = success();
	return json;
    }

    @Override
    public JsonElement share(@PathVariable Integer userId,
	    HttpServletRequest request) {
	User user = userService.selectByPrimaryKey(userId);
	AgAssert.notNull(user, SysTipsException.class, "非法请求,请重试!");
	JsonObject json = success();
	JsonObject dataObject = new JsonObject();
	if (StringUtil.isNotBlank(user.getCouponsCode())) {
	    dataObject.addProperty("headImg", user.getHeadImg());
	    dataObject.addProperty("nickName", user.getNickName());
	    dataObject.addProperty("couponsCode", user.getCouponsCode());
	}
	json.add("data", AGsonBuilder.create().toJsonTree(dataObject));
	return json;
    }

    /**
     * 参数组装
     * 
     * @param sex
     * @param faceshpe
     * @param colorofskin
     * @param bodySize
     * @param problem
     * @param style
     * @param heigh
     * @param weight
     * @param chest
     * @param waist
     * @param hip
     * @param professional
     * @param cityCode
     * @param birthday
     * @return
     */
    public UserInformation initData(Integer sex, String faceshpe,
	    String colorofskin, String bodySize, String[] problem,
	    String[] style, String heigh, String weight, String chest,
	    String waist, String hip, String professional, String cityCode,
	    String birthday) {
	UserInformation information = new UserInformation();
	information.setSex(sex);
	information.setFaceshpe(faceshpe);
	information.setColorofskin(colorofskin);
	information.setBodySize(bodySize);
	if (null != problem && problem.length > 0) {
	    information.setProblem(parser(problem));
	}
	if (null != style && style.length > 0) {
	    information.setStyle(parser(style));
	}
	information.setHeigh(heigh);
	information.setWeight(weight);
	information.setChest(chest);
	information.setWaist(waist);
	information.setHip(hip);
	if (StringUtil.isNotBlank(professional)) {
	    information.setProfessional(professional);
	}
	if (StringUtil.isNotBlank(cityCode)) {
	    information.setCityCode(cityCode);
	}
	if (StringUtil.isNotBlank(birthday)) {
	    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	    Long _barthday;
	    try {
		_barthday = sdf.parse(birthday).getTime() / 1000;
		information.setBirthday(_barthday);
	    } catch (ParseException e) {
		e.printStackTrace();
	    }
	}
	return information;
    }

    public String doUploadImg(MultipartFile[] _imgs,
	    HttpServletRequest request, String[] lifeImgIds) {
	String resultPath = "";
	if (null != lifeImgIds) {
	    for (String lifeImgId : lifeImgIds) {
		resultPath += lifeImgId + StylistConstants.SPE_SUX;
	    }
	}
	if (null == _imgs || _imgs.length == 0) {
	    return resultPath;
	}

	for (MultipartFile multipartFile : _imgs) {
	    if (null != multipartFile) {
		String uploadId = cosFileService.saveFileForId(multipartFile,
			StylistConstants.UploadType.LIFE, request);
		resultPath += uploadId + StylistConstants.SPE_SUX;
	    }
	}
	return StringUtil.isBlank(resultPath) ? null : resultPath;
    }

    public boolean checkParameter(Integer sex, String faceshpe,
	    String colorofskin, String bodySize, String[] problem,
	    String[] style, String heigh, String weight, String chest,
	    String waist, String hip, String professional, String countyCode,
	    String birthday) {
	if (sex != StylistConstants.Sex.LADY && sex != StylistConstants.Sex.MAN)
	    throw new InvalidParamException("性别参数非法!");
	if (StringUtil.isBlank(faceshpe) || !checkFaceshpe(faceshpe, sex))
	    throw new InvalidParamException("脸型参数非法!");
	if (StringUtil.isBlank(colorofskin)
		|| !checkColorofSkin(colorofskin, sex))
	    throw new InvalidParamException("肤色参数非法!");
	if (StringUtil.isNotBlank(bodySize) && !checkBodySize(bodySize, sex))
	    throw new InvalidParamException("体型参数非法!");
	if (null != problem && !checkProblem(problem, sex))
	    throw new InvalidParamException("解决问题参数非法!");
	if (null != style && !checkStyle(style, sex))
	    throw new InvalidParamException("喜好风格参数非法!");
	if (StringUtil.isBlank(heigh))
	    throw new InvalidParamException("身高参数非法!");
	if (StringUtil.isBlank(weight))
	    throw new InvalidParamException("体重参数非法!");
	if (StringUtil.isBlank(chest))
	    throw new InvalidParamException("胸围参数非法!");
	if (StringUtil.isBlank(waist))
	    throw new InvalidParamException("腰围参数非法!");
	if (StringUtil.isBlank(hip))
	    throw new InvalidParamException("臀围参数非法!");
	if (StringUtil.isBlank(countyCode)) {
	    throw new InvalidParamException("县区参数非法！");
	} else {
	    StylistCity city = stylistCityService
		    .selectByPrimaryKey(new Integer(countyCode));
	    if (!(null != city && city.getLevelType().equals("3"))) {
		throw new InvalidParamException("请选择正确的区县！");
	    }
	}

	/*
	 * if (StringUtil.isBlank(professional)) throw new
	 * InvalidParamException("职业参数非法!"); if (StringUtil.isBlank(cityCode))
	 * throw new InvalidParamException("城市参数非法!"); if
	 * (StringUtil.isBlank(birthday)) throw new
	 * InvalidParamException("生日参数非法!");
	 */
	return true;
    }

    /**
     * 脸型参数检查
     * 
     * @param _faceshpe
     * @return
     */
    public boolean checkFaceshpe(String _faceshpe, Integer _sex) {
	return UserInfoConfig.CHECK_FACESHPE(_sex, _faceshpe);
    }

    /**
     * 肤色参数检查
     * 
     * @param _faceshpe
     * @return
     */
    public boolean checkColorofSkin(String _colorofSkin, Integer _sex) {
	return UserInfoConfig.CHECK_COLOROFSKIN(_sex, _colorofSkin);
    }

    /**
     * 体型参数检查
     * 
     * @param _faceshpe
     * @return
     */
    public boolean checkBodySize(String _bodySize, Integer _sex) {
	return UserInfoConfig.CHECK_SIZE(_sex, _bodySize);
    }

    /**
     * 解决问题参数检查
     * 
     * @param _faceshpe
     * @return
     */
    public boolean checkProblem(String[] _problem, Integer _sex) {
	return UserInfoConfig.CHECK_PROBLEM(_sex, _problem);
    }

    /**
     * 喜好风格参数检查
     * 
     * @param _faceshpe
     * @return
     */
    public boolean checkStyle(String[] _style, Integer _sex) {
	return UserInfoConfig.CHECK_STYLE(_sex, _style);
    }

    /**
     * 解析数组，拼装
     * 
     * @param arr
     * @return
     */
    public String parser(String[] arr) {
	String str = "";
	if (null != arr && arr.length >= 1) {
	    for (String elemt : arr) {
		str += elemt + RequirementConfig.SPE_SUX;
	    }
	}
	return str;
    }

    @Override
    public @ResponseBody JsonElement config(HttpServletRequest request) {
	JsonObject json = new JsonObject();
	json.addProperty("性别_男_sex", StylistConstants.Sex.MAN);
	json.addProperty("性别_女_sex", StylistConstants.Sex.LADY);

	json.addProperty("脸型_男_faceshpe", dbValues(UserInfoConfig.FACESHPE_MAN));
	json.addProperty("脸型_女_faceshpe",
		dbValues(UserInfoConfig.FACESHPE_LADY));

	json.addProperty("肤色_男_colorofskin",
		dbValues(UserInfoConfig.COLOROFSKIN_MAN));
	json.addProperty("肤色_女_colorofskin",
		dbValues(UserInfoConfig.COLOROFSKIN_LADY));

	json.addProperty("体型_男_bodySize", dbValues(UserInfoConfig.SIZE_MAN));
	json.addProperty("体型_女_bodySize", dbValues(UserInfoConfig.SIZE_LADY));

	json.addProperty("解决问题_男_problem", dbValues(UserInfoConfig.PROBLEM_MAN));
	json.addProperty("解决问题_女_problem",
		dbValues(UserInfoConfig.PROBLEM_LADY));

	json.addProperty("风格偏好_男_style", dbValues(UserInfoConfig.STYLE_MAN));
	json.addProperty("风格偏好_女_style", dbValues(UserInfoConfig.STYLE_LADY));

	return json;
    }

    public String dbValues(String arvariable) {
	Map<String, String> shopMap = DictionarySettingUtils
		.getParameterMap(arvariable);
	String str = "";
	for (Entry<String, String> entry : shopMap.entrySet()) {
	    str += entry.getKey() + ":'" + entry.getValue() + "'";
	}
	return str;
    }

}
